////////////////////////////////////////////////////////////////////////////////
//
//  Copyright (C) 2003-2006 Adobe Macromedia Software LLC and its licensors.
//  All Rights Reserved. The following is Source Code and is subject to all
//  restrictions on such code as contained in the End User License Agreement
//  accompanying this product.
//
////////////////////////////////////////////////////////////////////////////////

package mx.charts.series
{

import mx.charts.HitData;
import mx.charts.chartClasses.HLOCSeriesBase;
import mx.charts.renderers.CandlestickItemRenderer;
import mx.charts.series.items.HLOCSeriesItem;
import mx.charts.styles.HaloDefaults;
import mx.core.ClassFactory;
import mx.core.mx_internal;
import mx.graphics.IFill;
import mx.graphics.IStroke;
import mx.graphics.SolidColor;
import mx.graphics.Stroke;
import mx.styles.CSSStyleDeclaration;
import mx.charts.chartClasses.GraphicsUtilities;

use namespace mx_internal;

include "../styles/metadata/FillStrokeStyles.as"

/**
 *  Sets the declining fill for this data series, used when the closing value of an element is less than the opening value. You can specify either an object implementing the IFill interface, 
 *  or a number representing a solid color value. You can also specify a solid fill using CSS. 
 */
[Style(name="declineFill", type="mx.graphics.IFill", inherit="no")]

/**
 *  Sets the stroke style used to outline the box defining the open-close region of the series.
 */
[Style(name="boxStroke", type="mx.graphics.IStroke", inherit="no")]

/**
 *  Represents financial data as a series of candlesticks representing the high, low, opening, and closing values of a data series.
 *  The top and bottom of the vertical line in each candlestick represent the high and low values for the datapoint, while the top and bottom of the filled box represent
 *  the opening and closing values. Each candlestick is filled differently depending on whether the closing value for the datapoint is higher or lower than the opening value.
 *
 *  @mxml
 *  <p>
 *  The <code>&lt;mx:CandlestickSeries&gt;</code> tag inherits all the properties of its parent classes, and 
 *  the following properties:
 *  </p>
 *  <pre>
 *  &lt;mx:CandlestickSeries
 *    <strong>Styles</strong>
 *    boxStroke="<i>IStroke; no default</i>"
 *    declineFill="<i>IFill; no default</i>"
 *    fill="<i>IFill; no default</i>"
 *    stroke="<i>IStroke; no default</i>"  
 *  /&gt;
 *  </pre>
 *  
 *  @see mx.charts.CandlestickChart
 *  
 *  @includeExample ../examples/CandlestickChartExample.mxml
 *  
 */
public class CandlestickSeries extends HLOCSeriesBase
{
    include "../../core/Version.as";

	//--------------------------------------------------------------------------
	//
	//  Class initialization
	//
	//--------------------------------------------------------------------------

	/**
	 *  @private
	 */
	private static var stylesInited:Boolean = initStyles();	

	/**
	 *  @private
	 */
	private static function initStyles():Boolean
	{
		HaloDefaults.init();

		var candlestickSeriesStyle:CSSStyleDeclaration =
			HaloDefaults.createSelector("CandlestickSeries");		

		candlestickSeriesStyle.defaultFactory = function():void
		{
			this.boxStroke = new Stroke(0, 0);
			this.declineFill = new SolidColor(0);
			this.fill = new SolidColor(0xFFFFFF);
			this.itemRenderer = new ClassFactory(CandlestickItemRenderer);
			this.stroke = new Stroke(0, 0);
		}

		return true;
	}

	//--------------------------------------------------------------------------
	//
	//  Constructor
	//
	//--------------------------------------------------------------------------
	
	/**
	 *  Constructor.
	 */	
	public function CandlestickSeries()
	{
		super();
	}

	/* 
	 *  @copy mx.charts.chartClasses.IChartElement#findDataPoints()
	 */
	override public function findDataPoints(x:Number,y:Number,sensitivity:Number):Array
	{
		if (interactive == false)
			return [];
			
			
		
		var minDist:Number = _renderData.renderedHalfWidth + sensitivity;
		var minItem:HLOCSeriesItem;		

		var len:uint = _renderData.filteredCache.length;
		var i:uint;
		
		for (i=0;i<len;i++)
		{
			var v:HLOCSeriesItem = _renderData.filteredCache[i];
			
			var dist:Number = Math.abs((v.x + _renderData.renderedXOffset) - x);
			if (dist > minDist)
				continue;
				
				

			var lowValue:Number = Math.max(v.low,Math.max(v.high,v.close));
			var highValue:Number = Math.min(v.low,Math.min(v.high,v.close));
			if(!isNaN(v.open)) 
			{
				lowValue = Math.max(lowValue,v.open);
				highValue = Math.min(highValue,v.open);
			}

			if (highValue - y > sensitivity)
				continue;

			if (y - lowValue > sensitivity)
				continue;

				
			minDist = dist;
			minItem = v;
			if (dist < _renderData.renderedHalfWidth)
			{
				// we're actually inside the column, so go no further.
				break;
			}
		}

		if (minItem != null)
		{
			var ypos:Number = (minItem.open + minItem.close)/2;
			var id:uint = minItem.index;
			var hd:HitData = new HitData(createDataID(id),Math.sqrt(minDist),minItem.x + _renderData.renderedXOffset,ypos,minItem);
			var f:Object = getStyle("declineFill");
			
			hd.contextColor = GraphicsUtilities.colorFromFill(f);
			
			hd.dataTipFunction = formatDataTip;
			return [hd];
		}
		return [];
	}
}

}
